﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace BasicGridCollisionDemo
{
    public class Grid
    {
        public readonly int NLines;
        public readonly int NColumns;

        public readonly int CellWidth;
        public readonly int CellHeight;

        public readonly List<int>[] Cells;

        public Grid(int columns, int lines, int width, int height)
        {
            Cells = new List<int>[lines * columns];
            NLines = lines;
            NColumns = columns;

            CellWidth = width;
            CellHeight = height;

            for(int i=0; i< Cells.Length; i++)
            {
                Cells[i] = new List<int>();
            }
        }
        

        public void UpdateObject(CellObject cellObject)
        {
            RemoveObject(cellObject);
            AddObject(cellObject);
        }

        private void AddObject(CellObject cellObject)
        {
            int left = (int) Math.Floor(cellObject.BoundingRectangle.Left / CellWidth);
            int right = (int)Math.Floor(cellObject.BoundingRectangle.Right / CellWidth);

            int top = (int)Math.Floor(cellObject.BoundingRectangle.Top / CellHeight);
            int bottom = (int)Math.Floor(cellObject.BoundingRectangle.Bottom / CellHeight);

            for (int i = left; i <= right; i++)
            {
                for (int j = top; j <= bottom; j++)
                {
                    int cellIndex = i + j * NLines;
                    Cells[cellIndex].Add(cellObject.Id);
                    cellObject.CellNums.Add(cellIndex);
                }
            }
        }

        private  void RemoveObject(CellObject cellObject)
        {
            //Remove the object from the cell
            for (int i = 0; i < cellObject.CellNums.Count; i++)
            {
                Cells[cellObject.CellNums[i]].Remove(cellObject.Id);
            }

            //Remove the cells from the object
            cellObject.ClearCellNumbers();
        }

        public List<int> GetObjectIds(Point point)
        {
            return GetObjectIds(point.X, point.Y);
        }

        public List<int> GetObjectIds(int column, int line)
        {
            return Cells[column + line*NColumns];
        }

        public List<int> GetObjectIds(Rectangle rectangle)
        {
            List<int> ids = new List<int>();

            for (int i = rectangle.Left; i <= rectangle.Right; i++)
            {
                for (int j = rectangle.Top; j < rectangle.Bottom; j++)
                {

                    foreach (int num in Cells[i + j * NColumns])
                    {
                        if (!ids.Contains(num))
                            ids.Add(num);
                    }
                }
            }

            return ids;
        }
    }
}
